import { createApp } from 'vue';
import { Subject } from 'rxjs';
import AppDrawer from '../../components/common/app-drawer';
import { IPSAppView } from '@ibiz/dynamic-model-api';
import { IParam } from 'ibz-core';
import { LogUtil, Util } from 'ibz-core';
import { IonicVue, modalController } from '@ionic/vue';
import { ComponentRegister } from '../../register';
import { translate } from '../../locale';

/**
 * 抽屉工具
 *
 * @export
 * @class AppDrawerService
 */
export class AppDrawerService {
  /**
   * 实例对象
   *
   * @private
   * @static
   * @memberof AppDrawerService
   */
  private static readonly $drawer = new AppDrawerService();

  /**
   * 构造方法
   *
   * @memberof AppDrawerService
   */
  constructor() {
    if (AppDrawerService.$drawer) {
      return AppDrawerService.$drawer;
    }
  }

  /**
   * 获取实例对象
   *
   * @static
   * @returns
   * @memberof AppDrawerService
   */
  public static getInstance() {
    return AppDrawerService.$drawer;
  }

  /**
   * 打开 ionic 模式模态框
   *
   * @private
   * @param {*} ele
   * @param {string} uuid
   * @return {*}  {Promise<any>}
   * @memberof AppDrawerService
   */
  private async createDrawer(ele: any, uuid: string): Promise<any> {
    const modal = await modalController.create({
      component: ele,
      animated: false,
      id: uuid,
      cssClass: 'app-modal',
    });
    await modal.present();
    return modal;
  }

  /**
   *  创建 Vue 实例对象
   *
   * @private
   * @param {({ viewComponentName?: string,viewModel: IParam, viewPath: string, customClass?: string, customStyle?: IParam, placement?: 'DRAWER_LEFT' | 'DRAWER_RIGHT' })} view
   * @param {*} [navContext={}]
   * @param {*} [navParam={}]
   * @param {Array<any>} [navDatas=[]]
   * @param {*} otherParam
   * @param {string} uuid
   * @return {*}  {Promise<void>}
   * @memberof AppDrawerService
   */
  private async createVueExample(
    view: {
      viewComponentName?: string;
      viewModel?: IParam;
      viewPath?: string;
      customClass?: string;
      customStyle?: IParam;
      placement?: 'DRAWER_LEFT' | 'DRAWER_RIGHT';
    },
    navContext: any = {},
    navParam: any = {},
    navDatas: Array<any> = [],
    otherParam: any,
    uuid: string,
    subject: Subject<any>,
  ): Promise<void> {
    const model = await this.createDrawer(null, uuid);
    const parentEle = document.getElementById(`${uuid}`)?.getElementsByClassName('ion-page')?.[0];
    const props = { view, navContext, navParam, navDatas, otherParam, model, subject };
    const vm = createApp(AppDrawer, props)
      .use(ComponentRegister)
      .use(App.getUserRegister())
      .use(IonicVue)
      .use(App.getI18n());
    // 添加全局翻译api
    vm.config.globalProperties.$tl = function (key: string, value?: string) {
      return translate(key, this, value);
    };
    vm.config.warnHandler = (msg: any, vm: any, trace: any) => {
      if (
        !msg.startsWith('Extraneous non-emits') &&
        !msg.startsWith('Extraneous non-props') &&
        !msg.startsWith('injection')
      ) {
        console.warn(msg, trace);
      }
    };
    const subscribe = subject.subscribe(() => {
      vm.unmount();
      subscribe.unsubscribe();
    });
    if (parentEle) {
      vm.mount(parentEle);
    }
  }

  /**
   * 打开抽屉
   *
   * @param {({ viewComponent?: any, viewModel: IParam,viewPath: string, customClass?: string, customStyle?: IParam, placement?: 'DRAWER_LEFT' | 'DRAWER_RIGHT' })} view
   * @param {*} [navContext={}]
   * @param {*} [navParam={}]
   * @param {Array<any>} [navDatas=[]]
   * @param {*} [otherParam={}]
   * @return {*}  {Subject<any>}
   * @memberof AppDrawer
   */
  public openDrawer(
    view: {
      viewComponent?: any;
      viewModel?: IParam;
      viewPath?: string;
      customClass?: string;
      customStyle?: IParam;
      placement?: 'DRAWER_LEFT' | 'DRAWER_RIGHT';
    },
    navContext: any = {},
    navParam: any = {},
    navDatas: Array<any> = [],
    otherParam: any = {},
  ): Subject<any> {
    const subject: Subject<{ ret: boolean; datas?: IParam[] }> = new Subject<{ ret: boolean; datas?: IParam[] }>();
    try {
      const _navContext: any = {};
      Object.assign(_navContext, navContext);
      if (!view.viewComponent || !view.placement) {
        this.fillView(view);
      }
      const uuid = Util.createUUID();
      this.createVueExample(view, _navContext, navParam, navDatas, otherParam, uuid, subject);
      return subject;
    } catch (error) {
      LogUtil.warn(error);
      return subject;
    }
  }

  /**
   *  初始化视图名称
   *
   * @memberof AppModal
   */
  public fillView(view: any) {
    if (Util.isEmpty(view.viewModel)) {
      return;
    } else {
      view.viewComponent = App.getComponentService().getViewTypeComponent(
        (view.viewModel as IPSAppView).viewType,
        (view.viewModel as IPSAppView).viewStyle,
        (view.viewModel as IPSAppView)?.getPSSysPFPlugin()?.pluginCode,
      );
      if (!view.placement) {
        view.placement = (view.viewModel as IPSAppView).openMode;
      }
      view.viewPath = (view.viewModel as IPSAppView).modelPath;
    }
  }
}
